﻿using Microsoft.Xna.Framework;
using MoreEvent.Common.Systems;
using MoreEvent.Content.Buffs;
using MoreEvent.Content.Projectiles;
using MoreEvent.Content.Skies;
using System;
using System.Collections.Generic;
using System.Linq;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace MoreEvent.Common.Players
{
    public class EventPlayer : ModPlayer
    {
        public readonly Dictionary<int, byte> auroraVisuals = new()
        {
            { AuroraOverlay.Base, 0 }
        };
        public bool AuroraActive => GetAuroraType() != -1;
        public bool InLocalAurora => auroraVisuals.Any(x => x.Value > 0);

        private const byte Duration = 30;
        private int _priority = -1;
        public bool heatEffect;

        public override void ResetEffects()
        {
            heatEffect = false;
        }

        public void SetLocalAurora(int type)
        {
            if (_priority == -1)
            {
                auroraVisuals[type] = (byte)Math.Min(auroraVisuals[type] + 1, Duration);
                _priority = type;
            }
        }

        public float GetAuroraIntensity(int type) => MathHelper.Clamp(auroraVisuals[type] / (float)Duration * 1.25f, 0, 1);

        public void Reset()
        {
            for (int i = 0; i < AuroraOverlay.COUNT; i++)
            {
                if (i != _priority)
                {
                    auroraVisuals[i] = (byte)Math.Max(auroraVisuals[i] - 1, 0);
                }
            }
            _priority = -1;
        }
        public int GetAuroraType()
        {
            if (Main.dayTime || !EventSystem.AuroraActive || (Main.raining && !Player.ZoneSnow) || Player.ZoneCorrupt || Player.ZoneCrimson)
            {
                return -1;
            }
            if (EventSystem.ActiveEvents.Contains(7) && (Player.ZoneSnow || Player.ZoneSkyHeight))
            {
                return AuroraOverlay.Base;
            }
            return -1;
        }       
        public override void PreUpdate()
        {
            if (EventSystem.ActiveEvents.Contains(7) && InLocalAurora)
            {
                Player.luck += 0.3f;
                Player.AddBuff(BuffID.PeaceCandle, 2);
            }
            if (EventSystem.ActiveEvents.Contains(5) && Player.ZoneOverworldHeight)
            {
                int num16 = (int)Player.Center.X / 16;
                int num17 = (int)Player.Center.Y / 16;
                if (Main.tile[num16, num17 + 1].WallType == WallID.None || Main.tile[num16, num17].WallType == WallID.None)
                {
                    Player.AddBuff(ModContent.BuffType<Heatstroke>(), 61, true);
                }
            }
            if (heatEffect)
            {
                Player player = Player;
                player.velocity.X *= 0.95f;
            }
            if (EventSystem.ActiveEvents.Contains(3) && Main.rand.NextBool(80) && Player.ZoneOverworldHeight && !Player.ZoneDesert)
            {
                Vector2 vector2;
                vector2 = new((float)(Player.position.X + Player.width * 0.5 + (double)(Main.rand.Next(201) * -(double)Player.direction) + (Main.mouseX + (double)Main.screenPosition.X - Player.position.X)), (float)(Player.position.Y + Player.height * 0.5 - 600.0));
                vector2.X = (float)((vector2.X + (double)Player.Center.X) / 2.0) + Main.rand.Next(-200, 201);
                vector2.Y -= 100f;
                float num40 = Main.rand.Next(-30, 30);
                float num41 = 100f;
                if ((double)num41 < 0.0)
                {
                    num41 *= -1f;
                }
                if ((double)num41 < 20.0)
                {
                    num41 = 20f;
                }
                float num42 = (float)Math.Sqrt((double)num40 * (double)num40 + (double)num41 * (double)num41);
                float num43 = 10f / num42;
                float num44 = num40 * num43;
                float num45 = num41 * num43;
                float num46 = num44 + Main.rand.Next(-40, 41) * 0.02f;
                float num47 = num45 + Main.rand.Next(-40, 41) * 0.02f;
                int num48 = Projectile.NewProjectile(Player.GetSource_FromThis(), Player.Center.X + Main.rand.Next(-1000, 1000), Player.Center.Y + Main.rand.Next(-1200, -900), num46, num47, ModContent.ProjectileType<FrenchFrie3>(), 1, 3f, Main.myPlayer, 0f, 1f);
                Main.projectile[num48].friendly = true;
                Main.projectile[num48].hostile = true;
            }
            if (EventSystem.ActiveEvents.Contains(4) && Main.rand.NextBool(12) && Player.ZoneOverworldHeight && !Player.ZoneDesert)
            {
                Vector2 vector2;
                vector2 = new((float)(Player.position.X + Player.width * 0.5 + (double)(Main.rand.Next(201) * -(double)Player.direction) + (Main.mouseX + (double)Main.screenPosition.X - Player.position.X)), (float)(Player.position.Y + Player.height * 0.5 - 600.0));
                vector2.X = (float)((vector2.X + (double)Player.Center.X) / 2.0) + Main.rand.Next(-200, 201);
                vector2.Y -= 100f;
                float num40 = Main.rand.Next(-30, 30);
                float num41 = 100f;
                if ((double)num41 < 0.0)
                {
                    num41 *= -1f;
                }
                if ((double)num41 < 20.0)
                {
                    num41 = 20f;
                }
                float num42 = (float)Math.Sqrt((double)num40 * (double)num40 + (double)num41 * (double)num41);
                float num43 = 10f / num42;
                float num44 = num40 * num43;
                float num45 = num41 * num43;
                float num46 = num44 + Main.rand.Next(-40, 41) * 0.02f;
                float num47 = num45 + Main.rand.Next(-40, 41) * 0.02f;
                int num48 = Projectile.NewProjectile(Player.GetSource_FromThis(), Player.Center.X + Main.rand.Next(-1000, 1000), Player.Center.Y + Main.rand.Next(-1200, -900), num46, num47, ModContent.ProjectileType<Knife>(), 12, 3f, Main.myPlayer, 0f, 1f);
                Main.projectile[num48].friendly = true;
                Main.projectile[num48].hostile = true;
            }
            if (EventSystem.ActiveEvents.Contains(6) && !Player.ZoneDesert && Player.ZoneOverworldHeight)
            {
                if (Main.rand.NextBool(20))
                {
                    int num2 = Main.rand.Next(Main.screenWidth + 1000) - 500;
                    int num3 = (int)Main.screenPosition.Y - Main.rand.Next(50);
                    if (Main.LocalPlayer.velocity.Y > 0.0)
                    {
                        num3 -= (int)Main.LocalPlayer.velocity.Y;
                    }
                    if (Main.rand.NextBool(5))
                    {
                        num2 = Main.rand.Next(500) - 500;
                    }
                    else if (Main.rand.NextBool(5))
                    {
                        num2 = Main.rand.Next(500) + Main.screenWidth;
                    }
                    if (num2 < 0 || num2 > Main.screenWidth)
                    {
                        num3 += Main.rand.Next((int)(Main.screenHeight * 0.8)) + (int)(Main.screenHeight * 0.1);
                    }
                    int num4 = num2 + (int)Main.screenPosition.X;
                    int num5 = num4 / 16;
                    int num6 = num3 / 16;
                    if (Main.tile[num5, num6] != null && Main.tile[num5, num6].WallType == WallID.None)
                    {
                        int num7 = Dust.NewDust(new Vector2(num4, num3), 10, 10, DustID.Snow, 0f, 0f, 0, default, 1f);
                        Main.dust[num7].scale += Main.cloudAlpha * 0.2f;
                        Main.dust[num7].velocity.Y = (float)(3.0 + Main.rand.Next(30) * 0.100000001490116);
                        Dust dust = Main.dust[num7];
                        dust.velocity.Y *= Main.dust[num7].scale;
                        if (!Main.raining)
                        {
                            Main.dust[num7].velocity.X = Main.windSpeedCurrent + Main.rand.Next(-10, 10) * 0.1f;
                            Dust dust2 = Main.dust[num7];
                            dust2.velocity.X += (float)(Main.windSpeedCurrent * (double)Main.cloudAlpha * 10.0);
                        }
                        else
                        {
                            Main.dust[num7].velocity.X = (float)(Math.Sqrt((double)Math.Abs(Main.windSpeedCurrent)) * Math.Sign(Main.windSpeedCurrent) * (Main.cloudAlpha + 0.5) * 25.0 + (double)Main.rand.NextFloat() * 0.200000002980232 - 0.100000001490116);
                            Dust dust3 = Main.dust[num7];
                            dust3.velocity.Y *= 0.5f;
                        }
                        Dust dust4 = Main.dust[num7];
                        dust4.velocity.Y *= (float)(1.0 + 0.300000011920929 * Main.cloudAlpha);
                        Main.dust[num7].scale += Main.cloudAlpha * 0.2f;
                        Main.dust[num7].velocity *= (float)(1.0 + Main.cloudAlpha * 0.5);
                    }
                }
            }
        }
    }
}
